#include "LockFile.h"

LockFile :: LockFile ( const char* nombre, bool overwrite ) {

	this->fileName = nombre;

	this->fl.l_type = F_WRLCK;
	this->fl.l_whence = SEEK_SET;
	this->fl.l_start = 0;
	this->fl.l_len = 0;

	this->fd = -1;

	this->open(overwrite);
}

int LockFile :: lock (lock_t type) {

	if (type == write_lock)
		this->fl.l_type = F_WRLCK;
	else if (type == read_lock)
		this->fl.l_type = F_RDLCK;
	else return -1;

	this->fl.l_pid = getpid ();

	int resultado = fcntl ( this->fd,F_SETLKW,&(this->fl) );

	return resultado;
}

int LockFile :: unlock () {

	this->fl.l_pid = getpid ();

	this->fl.l_type = F_UNLCK;
	int resultado = fcntl ( this->fd,F_SETLK,&(this->fl) );
	return resultado;
}

int LockFile :: append ( const char* buffer,int buffsize ) {

	int resultado = -1;

	if ( this->fd > 0) {
		lseek ( this->fd,0,SEEK_END );
		resultado = ::write ( this->fd,buffer,buffsize );
	}
	return resultado;
}

int LockFile :: write ( const char* buffer,int buffsize ) {

	int resultado = -1;

	if ( this->fd > 0)
		resultado = ::write ( this->fd,buffer,buffsize );

	return resultado;
}

int LockFile :: read ( char* buffer,int buffsize ) {

	int resultado = -1;

	if ( this->fd > 0)
		resultado = ::read ( this->fd,buffer,buffsize );

	return resultado;
}

size_t LockFile :: seek ( size_t pos ) {
	size_t resultado = 0;

	if ( this->fd > 0)
		resultado = lseek ( this->fd,pos,SEEK_SET );

	return resultado;
}

size_t LockFile :: size () {
	size_t resultado = 0;

	if ( this->fd > 0) {

		size_t curr = lseek(this->fd,0, SEEK_CUR);
		resultado = lseek ( this->fd,0,SEEK_END );
		lseek(this->fd, curr, SEEK_SET);
	}

	return resultado;
}

bool LockFile:: isOpen()
{
	return (this->fd > 0);
}

int LockFile :: getFileDescriptor()
{
	return this->fd;
}

void LockFile::open(bool overwrite)
{
	if ( this->fd <= 0)
	{
		if (overwrite)
			this->fd = ::open ( this->fileName.c_str(), O_TRUNC | O_RDWR, 0777 );
		else
			this->fd = ::open ( this->fileName.c_str(), O_CREAT | O_RDWR, 0777 );
	}
}

void LockFile::close()
{
	::close ( this->fd );
	this->fd = -1;
}

LockFile :: ~LockFile () {
	unlock();
	close();
}
